From 625141e5d7a0076eddf421cd7afccefce9cb000e Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 20 Dec 2006 10:14:50 +0000 Subject: [PATCH] [HVM][SVM] Modify the interrupt/event injection logic. Resolves performance issues concerning AMD-V virtual interrupt/event injection: - Remove extra VINTRs vmexits, and only setup fake interrupt if intr pending. - Allow both event injection and interrupt injection concurrently in vmcb. Signed-off-by: Tom Woller --- xen/arch/x86/hvm/svm/intr.c | 33 ++++++++++++------------------ xen/arch/x86/hvm/svm/svm.c | 5 +---- xen/include/asm-x86/hvm/svm/vmcb.h | 1 - 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/xen/arch/x86/hvm/svm/intr.c b/xen/arch/x86/hvm/svm/intr.c index e42438aadb..97447d9f64 100644 --- a/xen/arch/x86/hvm/svm/intr.c +++ b/xen/arch/x86/hvm/svm/intr.c @@ -78,26 +78,6 @@ asmlinkage void svm_intr_assist(void) re_injecting = 1; } - /* - * If event requires injecting then do not inject int. - */ - if ( unlikely(v->arch.hvm_svm.inject_event) ) - { - v->arch.hvm_svm.inject_event = 0; - return; - } - - /* - * Create a 'fake' virtual interrupt on to intercept as soon - * as the guest _can_ take interrupts. - */ - if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow ) - { - vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR; - svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */ - return; - } - /* Previous interrupt still pending? */ if ( vmcb->vintr.fields.irq ) { @@ -124,7 +104,20 @@ asmlinkage void svm_intr_assist(void) hvm_set_callback_irq_level(); if ( cpu_has_pending_irq(v) ) + { + /* + * Create a 'fake' virtual interrupt on to intercept as soon + * as the guest _can_ take interrupts. Do not obtain the next + * interrupt from the vlapic/pic if unable to inject. + */ + if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow ) + { + vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR; + svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */ + return; + } intr_vector = cpu_get_interrupt(v, &intr_type); + } } /* have we got an interrupt to inject? */ diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index a5f39dacdf..ebb1e4f614 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -191,7 +191,6 @@ static inline void svm_inject_exception(struct vcpu *v, int trap, ASSERT(vmcb->eventinj.fields.v == 0); vmcb->eventinj = event; - v->arch.hvm_svm.inject_event=1; } static void stop_svm(void) @@ -2564,8 +2563,6 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs) exit_reason = vmcb->exitcode; save_svm_cpu_user_regs(v, regs); - v->arch.hvm_svm.inject_event = 0; - if (exit_reason == VMEXIT_INVALID) { svm_dump_vmcb(__func__, vmcb); @@ -2933,7 +2930,7 @@ asmlinkage void svm_asid(void) clear_bit( ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags ); } } - + /* * Local variables: * mode: C diff --git a/xen/include/asm-x86/hvm/svm/vmcb.h b/xen/include/asm-x86/hvm/svm/vmcb.h index 81d41ea688..3340ec3a9e 100644 --- a/xen/include/asm-x86/hvm/svm/vmcb.h +++ b/xen/include/asm-x86/hvm/svm/vmcb.h @@ -456,7 +456,6 @@ struct arch_svm_struct { u32 *msrpm; u64 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */ int saved_irq_vector; - u32 inject_event; u32 launch_core; u32 asid_core; -- 2.30.2